# 用于深度拷贝的copy工具包
import copy
import numpy as np
import math
import torch
import torch.nn as nn
from torch.autograd import Variable


# 在多头注意力机制的实现中, 用到多个结构相同的线性层.
# 我们将使用clone函数将他们一同初始化在一个网络层列表对象中. 之后的结构中也会用到该函数.
def clone_layers(module, n):
    """
    :param module: 要克隆的目标网络层
    :param n: 克隆的数量
    :return:
    """
    # 通过for循环对module进行N次深度拷贝, 使其每个module成为独立的层,
    # 将其放在nn.ModuleList列表中存放.
    return nn.ModuleList([copy.deepcopy(module) for _ in range(n)])



def test_view():
    torch.manual_seed(0)
    query = torch.arange(48).reshape(2, 3, 8)
    print(query)

    # multi_head_query = query.view(2, -1, 2, 2).transpose(1, 2)
    multi_head_query = query.view(2, -1, 2, 4)
    print(multi_head_query)


def test_view_2():
    torch.manual_seed(0)
    x = torch.randn(4, 4)
    print(x.size())
    #
    y = x.view(-1, 8) # -1是自适应维度
    print(y.size())

    #
    a = torch.randn(1,2,3,4)
    print(a.size())
    print(a)
    #
    b = a.transpose(1,2) # 交换2-3维度
    print(b.size())
    print(b)
    #
    c = a.view(1,3,2,4)
    print(c)


if __name__ == '__main__':
    # test_view()
    test_view_2()